package org.ravenhearte.engine.gui;

import java.util.Stack;

import org.ravenhearte.engine.input.EventHandler;

import com.jme.bounding.BoundingBox;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.ClipState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.RenderState.StateType;

public abstract class GUIElement extends Node implements EventHandler {
	/**
	 * 
	 */
	private static final long serialVersionUID = 155237140635417557L;
	
	protected Quad mesh;

	public GUIElement(String name) {
		super("GUI " + name);
		this.setZOrder(0);
	}
	
	@Override
	protected void applyRenderState(Stack<? extends RenderState>[] states) {		
		int dist0, dist1, dist2, dist3,
			pDist0, pDist1, pDist2, pDist3;
		
		Vector3f wT = getWorldTranslation();
		ClipState clipState = (ClipState) getRenderState(StateType.Clip);
		ClipState pCS = (ClipState) parent.getRenderState(StateType.Clip);
		
		if(pCS != null) {
			pDist0 = -(int) pCS.getPlaneEq(0, 3);
			pDist1 = (int) pCS.getPlaneEq(1, 3);
			pDist2 = -(int) pCS.getPlaneEq(2, 3);
			pDist3 = (int) pCS.getPlaneEq(3, 3);

	        dist0 = (int) (wT.x - mesh.getWidth() / 2);
	        dist1 = (int) (wT.x + mesh.getWidth() / 2);
	        dist2 = (int) (wT.y - mesh.getHeight() / 2);
	        dist3 = (int) (wT.y + mesh.getHeight() / 2);

	        if(pDist0 > dist0) {
	        	dist0 = pDist0;
	        }
	        if(pDist1 < dist1) {
	        	dist1 = pDist1;
	        }
	        if(pDist2 > dist2) {
	        	dist2 = pDist2;
	        }
	        if(pDist3 < dist3) {
	        	dist3 = pDist3;
	        }
		}
		else {
	        dist0 = (int) (wT.x - mesh.getWidth() / 2);
	        dist1 = (int) (wT.x + mesh.getWidth() / 2);
	        dist2 = (int) (wT.y - mesh.getHeight() / 2);
	        dist3 = (int) (wT.y + mesh.getHeight() / 2);
		}

		if (clipState != null) {
			clipState.setClipPlaneEquation( ClipState.CLIP_PLANE0,
					1, 0, 0, -dist0 );
			clipState.setClipPlaneEquation( ClipState.CLIP_PLANE1,
					-1, 0, 0, dist1 );
			clipState.setClipPlaneEquation( ClipState.CLIP_PLANE2,
					0, 1, 0, -dist2 );
			clipState.setClipPlaneEquation( ClipState.CLIP_PLANE3,
					0, -1, 0, dist3 );
		}
		
		float boundingWidth = (dist1 - dist0) / 2;
		float boundingHeight = (dist3 - dist2) / 2;
		
		Vector3f boundingCenter = new Vector3f();
		boundingCenter.x = dist0 + boundingWidth - wT.x;
		boundingCenter.y = dist2 + boundingHeight - wT.y;
		boundingCenter.z = 0;
		
		mesh.setModelBound(new BoundingBox(boundingCenter, boundingWidth, boundingHeight, 1));
		
		super.applyRenderState(states);
	}
	
	@Override
	public int attachChild(Spatial child) {
		child.setZOrder(getZOrder() - 2, true);
		child.setZOrder(getZOrder() - 1);
		return super.attachChild(child);
	}
}
